﻿using DynORM.BLLMapper;
using DynORM.BLLMapper.Helpers;
using DynORM.Enums;
using DynORM.Interfaces;
using DynORM.Mappers;
using DynORM.ValueObjects;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DynORM.ER.Mappers
{
    public class Entity
    {
        public static object Read(Type bllObjType, string connectionString, DBMSTypes dbmsType,  params object[] bllObjIDs)
        {
            object result = null;

            result = ObjectAndRowAux.GetInstance(dbmsType).CreateBLLObj(bllObjType, connectionString, bllObjIDs);

            LazyLoadStatus.MarkAsGhost(result);

            return result;
        }

        public static IEnumerable<object> Read(Type bllObjType, string connectionString, DBMSTypes dbmsType)
        {
            return Read(bllObjType, connectionString, dbmsType, new List<BLLComparison>());
        }

        public static IEnumerable<object> Read(Type bllObjType, string connectionString, DBMSTypes dbmsType, IEnumerable<BLLComparison> predicate)
        {
            List<object> result = new List<object>();

            if (!TypeAndRowDescriptorAux.GetInstance(dbmsType).IsExistsInDB(bllObjType, connectionString))
                return result;

            result.AddRange(ObjectAndRowAux.GetInstance(dbmsType).CreateBLLObjs(bllObjType, connectionString, predicate));

            foreach(object obj in result)
                LazyLoadStatus.MarkAsGhost(obj);

            return result;
        }

        public static void StoreStructure(Type bllObjType, string connectionString, DBMSTypes dbmsType)
        {
            ObjectAndRowAux.GetInstance(dbmsType).StoreStructure(connectionString, bllObjType);
        }

        public static void Store(object bllObj, bool updateStructure, string connectionString, DBMSTypes dbmsType)
        {
            OptimisticLockChecker.CheckOptimisticLock(bllObj, connectionString, dbmsType);

            ObjectAndRowAux.GetInstance(dbmsType).StoreParentsPKsandFields(connectionString, bllObj, updateStructure);
        }

        public static void Delete(object bllObj, string connectionString, DBMSTypes dbmsType)
        {
            ObjectAndRowAux.GetInstance(dbmsType).DeleteBLLObj(bllObj, connectionString);
        }
    }
}
